"""上下文编排器 - 系统核心协调组件"""

import asyncio
from typing import Dict, Any, List, Optional, Union
from loguru import logger

from ..database.manager import DatabaseManager
from .memory_manager import MemoryManager
from .knowledge_processor import KnowledgeProcessor
from .conversation_manager import ConversationManager


class ContextOrchestrator:
    """上下文编排器 - 协调各个组件的交互"""
    
    def __init__(self, config: Dict[str, Any]):
        self.config = config
        self.app_config = config.get('app', {})
        self.db_config = config.get('database', {})
        
        # 初始化数据库管理器
        self.db_manager = DatabaseManager(config)
        
        # 初始化核心组件
        self.memory_manager = None
        self.knowledge_processor = None
        self.conversation_manager = None
        
        # 系统状态
        self.is_initialized = False
        self.active_sessions = {}
        
        logger.info("上下文编排器已创建")
    
    async def initialize(self):
        """初始化编排器和所有组件"""
        if self.is_initialized:
            logger.warning("上下文编排器已初始化")
            return
        
        try:
            # 初始化数据库连接
            await self.db_manager.initialize()
            
            # 初始化核心组件
            self.memory_manager = MemoryManager(self.db_manager, self.config)
            await self.memory_manager.initialize()
            
            self.knowledge_processor = KnowledgeProcessor(self.db_manager, self.config)
            await self.knowledge_processor.initialize()
            
            self.conversation_manager = ConversationManager(self.db_manager, self.config)
            await self.conversation_manager.initialize()
            
            self.is_initialized = True
            logger.info("上下文编排器初始化完成")
            
        except Exception as e:
            logger.error(f"初始化上下文编排器失败: {e}")
            raise
    
    async def shutdown(self):
        """关闭编排器和所有组件"""
        if not self.is_initialized:
            logger.warning("上下文编排器未初始化")
            return
        
        try:
            # 关闭核心组件
            if self.conversation_manager:
                await self.conversation_manager.shutdown()
            
            if self.knowledge_processor:
                await self.knowledge_processor.shutdown()
            
            if self.memory_manager:
                await self.memory_manager.shutdown()
            
            # 关闭数据库连接
            await self.db_manager.close()
            
            # 清理会话
            self.active_sessions.clear()
            
            self.is_initialized = False
            logger.info("上下文编排器已关闭")
            
        except Exception as e:
            logger.error(f"关闭上下文编排器失败: {e}")
    
    async def create_session(self, user_id: str, session_config: Optional[Dict[str, Any]] = None) -> str:
        """创建新的用户会话"""
        if not self.is_initialized:
            raise RuntimeError("上下文编排器未初始化")
        
        try:
            import uuid
            session_id = str(uuid.uuid4())
            
            # 创建会话配置
            config = session_config or {}
            config.update({
                'user_id': user_id,
                'session_id': session_id,
                'created_at': asyncio.get_event_loop().time(),
                'last_activity': asyncio.get_event_loop().time()
            })
            
            # 初始化会话上下文
            session_context = {
                'config': config,
                'memory_context': await self.memory_manager.create_user_context(user_id),
                'conversation_context': await self.conversation_manager.create_session(user_id, session_id),
                'knowledge_context': await self.knowledge_processor.create_user_context(user_id)
            }
            
            self.active_sessions[session_id] = session_context
            
            logger.info(f"创建会话: {session_id} for user {user_id}")
            return session_id
            
        except Exception as e:
            logger.error(f"创建会话失败: {e}")
            raise
    
    async def get_session(self, session_id: str) -> Optional[Dict[str, Any]]:
        """获取会话信息"""
        return self.active_sessions.get(session_id)
    
    async def close_session(self, session_id: str):
        """关闭会话"""
        if session_id not in self.active_sessions:
            logger.warning(f"会话不存在: {session_id}")
            return
        
        try:
            session_context = self.active_sessions[session_id]
            user_id = session_context['config']['user_id']
            
            # 保存会话状态
            await self.conversation_manager.close_session(session_id)
            
            # 清理内存中的会话
            del self.active_sessions[session_id]
            
            logger.info(f"关闭会话: {session_id} for user {user_id}")
            
        except Exception as e:
            logger.error(f"关闭会话失败: {e}")
    
    async def process_message(self, session_id: str, message: str, 
                            message_type: str = 'user') -> Dict[str, Any]:
        """处理用户消息"""
        if not self.is_initialized:
            raise RuntimeError("上下文编排器未初始化")
        
        session_context = self.active_sessions.get(session_id)
        if not session_context:
            raise ValueError(f"会话不存在: {session_id}")
        
        try:
            user_id = session_context['config']['user_id']
            
            # 更新会话活动时间
            session_context['config']['last_activity'] = asyncio.get_event_loop().time()
            
            # 1. 存储用户消息到对话管理器
            message_id = await self.conversation_manager.add_message(
                session_id, message, message_type, user_id
            )
            
            # 2. 检索相关记忆
            relevant_memories = await self.memory_manager.search_memories(
                user_id, message, limit=5
            )
            
            # 3. 检索相关知识
            relevant_knowledge = await self.knowledge_processor.search_knowledge(
                message, user_id, limit=3
            )
            
            # 4. 获取对话历史
            conversation_history = await self.conversation_manager.get_recent_messages(
                session_id, limit=10
            )
            
            # 5. 构建上下文
            context = {
                'message_id': message_id,
                'user_message': message,
                'conversation_history': conversation_history,
                'relevant_memories': relevant_memories,
                'relevant_knowledge': relevant_knowledge,
                'user_context': session_context['memory_context'],
                'session_info': session_context['config']
            }
            
            # 6. 生成响应（这里可以集成LLM）
            response = await self._generate_response(context)
            
            # 7. 存储助手响应
            response_id = await self.conversation_manager.add_message(
                session_id, response['content'], 'assistant', user_id
            )
            
            # 8. 更新记忆
            await self._update_memories(user_id, message, response['content'], context)
            
            # 9. 返回结果
            return {
                'message_id': message_id,
                'response_id': response_id,
                'response': response['content'],
                'context_used': {
                    'memories_count': len(relevant_memories),
                    'knowledge_count': len(relevant_knowledge),
                    'history_count': len(conversation_history)
                },
                'metadata': response.get('metadata', {})
            }
            
        except Exception as e:
            logger.error(f"处理消息失败: {e}")
            raise
    
    async def _generate_response(self, context: Dict[str, Any]) -> Dict[str, Any]:
        """生成响应（简化版本，实际应用中会集成LLM）"""
        try:
            # 这里是一个简化的响应生成逻辑
            # 在实际应用中，这里会调用LLM API
            
            user_message = context['user_message']
            memories = context['relevant_memories']
            knowledge = context['relevant_knowledge']
            history = context['conversation_history']
            
            # 构建简单的响应
            response_parts = []
            
            if memories:
                response_parts.append(f"基于您的历史记忆，我了解到相关信息。")
            
            if knowledge:
                response_parts.append(f"根据知识库，我找到了相关资料。")
            
            if not response_parts:
                response_parts.append(f"我收到了您的消息：{user_message}")
            
            response_content = " ".join(response_parts)
            
            return {
                'content': response_content,
                'metadata': {
                    'memories_used': len(memories),
                    'knowledge_used': len(knowledge),
                    'history_length': len(history),
                    'generation_method': 'simple_template'
                }
            }
            
        except Exception as e:
            logger.error(f"生成响应失败: {e}")
            return {
                'content': '抱歉，我在处理您的消息时遇到了问题。',
                'metadata': {'error': str(e)}
            }
    
    async def _update_memories(self, user_id: str, user_message: str, 
                             assistant_response: str, context: Dict[str, Any]):
        """更新用户记忆"""
        try:
            # 创建对话记忆
            memory_content = f"用户说：{user_message}\n助手回复：{assistant_response}"
            
            await self.memory_manager.store_memory(
                user_id=user_id,
                content=memory_content,
                memory_type='conversation',
                metadata={
                    'session_id': context['session_info']['session_id'],
                    'message_id': context['message_id'],
                    'context_used': context.get('context_used', {})
                }
            )
            
            # 更新用户状态
            await self.memory_manager.update_user_state(
                user_id, 
                {'last_interaction': asyncio.get_event_loop().time()}
            )
            
        except Exception as e:
            logger.error(f"更新记忆失败: {e}")
    
    async def search_memories(self, user_id: str, query: str, 
                            memory_types: Optional[List[str]] = None,
                            limit: int = 10) -> List[Dict[str, Any]]:
        """搜索用户记忆"""
        if not self.is_initialized:
            raise RuntimeError("上下文编排器未初始化")
        
        return await self.memory_manager.search_memories(
            user_id, query, memory_types, limit
        )
    
    async def upload_knowledge(self, content: str, title: str, 
                             user_id: Optional[str] = None,
                             metadata: Optional[Dict[str, Any]] = None) -> str:
        """上传知识文档"""
        if not self.is_initialized:
            raise RuntimeError("上下文编排器未初始化")
        
        return await self.knowledge_processor.upload_document(
            content, title, user_id, metadata
        )
    
    async def search_knowledge(self, query: str, user_id: Optional[str] = None,
                             limit: int = 5) -> List[Dict[str, Any]]:
        """搜索知识库"""
        if not self.is_initialized:
            raise RuntimeError("上下文编排器未初始化")
        
        return await self.knowledge_processor.search_knowledge(
            query, user_id, limit
        )
    
    async def get_user_context(self, user_id: str) -> Dict[str, Any]:
        """获取用户完整上下文"""
        if not self.is_initialized:
            raise RuntimeError("上下文编排器未初始化")
        
        try:
            # 获取用户记忆上下文
            memory_context = await self.memory_manager.get_user_context(user_id)
            
            # 获取用户对话历史
            conversation_context = await self.conversation_manager.get_user_conversations(user_id)
            
            # 获取用户知识上下文
            knowledge_context = await self.knowledge_processor.get_user_context(user_id)
            
            # 获取活跃会话
            active_sessions = []
            for session_id, session_context in self.active_sessions.items():
                if session_context['config']['user_id'] == user_id:
                    active_sessions.append({
                        'session_id': session_id,
                        'created_at': session_context['config']['created_at'],
                        'last_activity': session_context['config']['last_activity']
                    })
            
            return {
                'user_id': user_id,
                'memory_context': memory_context,
                'conversation_context': conversation_context,
                'knowledge_context': knowledge_context,
                'active_sessions': active_sessions,
                'total_sessions': len(active_sessions)
            }
            
        except Exception as e:
            logger.error(f"获取用户上下文失败: {e}")
            raise
    
    async def cleanup_inactive_sessions(self, max_inactive_seconds: int = 3600):
        """清理不活跃的会话"""
        current_time = asyncio.get_event_loop().time()
        inactive_sessions = []
        
        for session_id, session_context in self.active_sessions.items():
            last_activity = session_context['config']['last_activity']
            if current_time - last_activity > max_inactive_seconds:
                inactive_sessions.append(session_id)
        
        for session_id in inactive_sessions:
            await self.close_session(session_id)
        
        if inactive_sessions:
            logger.info(f"清理了 {len(inactive_sessions)} 个不活跃会话")
        
        return len(inactive_sessions)
    
    async def get_system_stats(self) -> Dict[str, Any]:
        """获取系统统计信息"""
        try:
            # 数据库健康状态
            db_health = await self.db_manager.health_check()
            
            # 活跃会话统计
            active_sessions_count = len(self.active_sessions)
            
            # 组件统计
            memory_stats = await self.memory_manager.get_stats() if self.memory_manager else {}
            knowledge_stats = await self.knowledge_processor.get_stats() if self.knowledge_processor else {}
            conversation_stats = await self.conversation_manager.get_stats() if self.conversation_manager else {}
            
            return {
                'system_status': 'initialized' if self.is_initialized else 'not_initialized',
                'active_sessions': active_sessions_count,
                'database_health': db_health,
                'components': {
                    'memory_manager': memory_stats,
                    'knowledge_processor': knowledge_stats,
                    'conversation_manager': conversation_stats
                },
                'timestamp': asyncio.get_event_loop().time()
            }
            
        except Exception as e:
            logger.error(f"获取系统统计失败: {e}")
            return {'error': str(e)}
    
    async def get_stats(self) -> Dict[str, Any]:
        """兼容别名：返回系统统计信息（等同于 get_system_stats）"""
        return await self.get_system_stats()
    
    async def health_check(self) -> Dict[str, Any]:
        """系统健康检查"""
        try:
            # 检查初始化状态
            initialized = self.is_initialized
            
            # 检查数据库健康
            db_health = await self.db_manager.health_check()
            db_healthy = all(db_health.values())
            
            # 检查组件健康
            components_healthy = True
            component_status = {}
            
            if self.memory_manager:
                memory_health = await self.memory_manager.health_check()
                component_status['memory_manager'] = memory_health
                components_healthy &= memory_health.get('healthy', False)
            
            if self.knowledge_processor:
                knowledge_health = await self.knowledge_processor.health_check()
                component_status['knowledge_processor'] = knowledge_health
                components_healthy &= knowledge_health.get('healthy', False)
            
            if self.conversation_manager:
                conversation_health = await self.conversation_manager.health_check()
                component_status['conversation_manager'] = conversation_health
                components_healthy &= conversation_health.get('healthy', False)
            
            overall_healthy = initialized and db_healthy and components_healthy
            
            return {
                'healthy': overall_healthy,
                'status': 'healthy' if overall_healthy else 'unhealthy',
                'checks': {
                    'initialized': initialized,
                    'database': db_healthy,
                    'components': components_healthy
                },
                'database_health': db_health,
                'component_health': component_status,
                'active_sessions': len(self.active_sessions)
            }
            
        except Exception as e:
            logger.error(f"健康检查失败: {e}")
            return {
                'healthy': False,
                'status': 'error',
                'error': str(e)
            }
    
    async def __aenter__(self):
        """异步上下文管理器入口"""
        await self.initialize()
        return self
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """异步上下文管理器出口"""
        await self.shutdown()